#include <Arduino.h>
#include <lvgl.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <TAMC_GT911.h>
#include "demos/lv_demos.h"
#include "demos/widgets/lv_demo_widgets.h"

#ifdef TAMC_GT911_H
#define TOUCH_RST 4  // T_CS
#define TOUCH_SCL 16 // T_CLK
#define TOUCH_INT 17 // T_PEN
#define TOUCH_SDA 18 // T_MOSI
#define TOUCH_WIDTH 480
#define TOUCH_HEIGHT 320
TAMC_GT911 tp = TAMC_GT911(TOUCH_SDA, TOUCH_SCL, TOUCH_INT, TOUCH_RST, TOUCH_WIDTH, TOUCH_HEIGHT);
#endif

TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[TFT_WIDTH * 10]; // 定义刷新缓存

// LVGL calls it when a rendered image needs to copied to the display
static void my_disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors((uint16_t *)&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp_drv);
}


#ifdef TAMC_GT911_H
// Read the touchpad
void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data)
{
    int32_t x, y;
    tp.read();
    bool touched = tp.isTouched;
    if (!touched)
    {
        data->state = LV_INDEV_STATE_RELEASED;
    }
    else
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->point.x = tp.points[0].x;
        data->point.y = tp.points[0].y;
    }
}
#endif

// Initialize your display and the required peripherals.
static void my_tft_init(void)
{
    //LCD屏幕初始化
    tft.begin(); /* TFT init */
    tft.setRotation(1);//为横屏方向
    tft.invertDisplay(1);
    //显示屏背光
    ledcSetup(10, 5000/*freq*/, 10 /*resolution*/);
    ledcAttachPin(TFT_BL, 10);
    analogReadResolution(10);
    ledcWrite(10,300);
}

void setup(void)
{
    Serial.begin(115200);
    Serial.println("LVGL Demo");

    pinMode(TFT_BL, OUTPUT);
    digitalWrite(TFT_BL, HIGH);

    my_tft_init();

    lv_init();
    lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * 10);

    //Initialize the display
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    //Change the following line to your display resolution
    disp_drv.hor_res = TFT_WIDTH;
    disp_drv.ver_res = TFT_HEIGHT;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register(&disp_drv);

    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello world!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); 
    lv_demo_widgets();
}

void loop()
{
    long last_time = millis();
    lv_task_handler(); // let the GUI do its work
    delay(5);          // let this time pass
    lv_tick_inc(int(millis() - last_time));
}
